﻿using Microsoft.EntityFrameworkCore;
using TuLing.Blazor.Dto;
using TulingMember.Core;

namespace TuLing.Blazor.Services
{
    /// <summary>
    /// 角色管理服务
    /// </summary>
    public class RBACService: BaseService
    {

        public RBACService(DefaultDbContext context) : base(context) { }
      
        public User? GetUser()
        {
            return _context.Users.Where(u => u.Id == AppSession.User!.Id).FirstOrDefault();
        }
        
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public void UpdatePwd(UpdatePwdInput input)
        {
            var user = AppSession.User;
            if (user == null)
            {
                throw new Exception("用户不存在");
            }

            if (!user.Password.Equals(input.OldPassword))
            {
                throw new Exception("旧密码错误");
            }

            user.Password = input.Password;
            _context.Users.Update(user);
            _context.SaveChanges();
        }

        /// <summary>
        /// 权限列表
        /// </summary>        
        public List<Permission> GetAuthList(SimpleInput input)
        {
            if (!string.IsNullOrEmpty(input.keyword))
            {
                return _context.Permissions.Where(m => m.UniqueCode.Contains(input.keyword) || m.UniqueName.Contains(input.keyword)).ToList();
            }
            return _context.Permissions.ToList();
        }

        /// <summary>
        /// 获取权限
        /// </summary>
        /// <param name="id">权限id</param>
        /// <returns>Security</returns>
        public Permission? GetAuthById(long id)
        {
            return _context.Permissions.FirstOrDefault(s=>s.Id == id);
        }        
        /// <summary>
        /// 获取我拥有的权限
        /// </summary>
        /// <returns></returns>
        public IEnumerable<long> GetMyAuth()
        {
                return _context.Users
                    .Where(u => u.Id == AppSession.User!.Id)
                    .SelectMany(u => u.UserRoles)
                    .Select(ur => ur.Role)
                    .SelectMany(r => r.RolePermissions)
                    .Select(rp => rp.Permission).Select(xx=> xx.Id);
        }
        
        /// <summary>
        /// 保存权限
        /// </summary>
        public Permission SaveAuth(Permission input)
        {
            if (input.Id == 0)
            {
                var first = _context.Permissions.FirstOrDefault(
                    m => m.UniqueCode == input.UniqueCode || 
                    m.UniqueName == input.UniqueName);
                
                if (first != null)
                {
                    if (first.UniqueCode == input.UniqueCode)
                        throw new Exception("已存在此权限编码");
                    if (first.UniqueName == input.UniqueName)
                        throw new Exception("已存在此权限名称");
                }
                _context.Permissions.Add(input);
                _context.SaveChanges();

                return _context.Permissions.OrderBy(s=>s.Id).Last();
            }
            else
            {
                var auth = _context.Permissions.FirstOrDefault(m =>
                    m.Id != input.Id && (m.UniqueCode == input.UniqueCode || 
                                         m.UniqueName == input.UniqueName));

                if (auth != null)
                {
                    if (auth.UniqueCode == input.UniqueCode)
                    {
                        throw new Exception("已存在此权限编码");
                    }
                    else if (auth.UniqueName == input.UniqueName)
                    {
                        throw new Exception("已存在此权限名称");
                    }
                }
                _context.Update(input);
                _context.SaveChanges();
                return input;
            }
        }
        /// <summary>
        /// 删除权限
        /// </summary>
        public void DeleteAuth(long id)
        {
            var auth = _context.Permissions.FirstOrDefault(s => s.Id == id);
            if (auth != null)
            {
                _context.Permissions.Remove(auth);
            }
            _context.SaveChanges();
        }

        /// <summary>
        /// 角色列表
        /// </summary> 
        public IEnumerable<Role> GetRole(SimpleInput input)
        {
            if (!string.IsNullOrEmpty(input.keyword))
            {
                return _context.Roles.Where(m => m.Name.Contains(input.keyword));
            }
            return _context.Roles.AsEnumerable();
        }

        /// <summary>
        /// 获取某个角色的权限
        /// </summary> 
        public IEnumerable<long> GetAuthByRoleId(long id)
        {
            var sql = _context.Roles
                .Where(u => u.Id == id)
                .SelectMany(r => r.RolePermissions)
                .Select(rp => rp.Permission)
                .Select(i => i.Id).ToQueryString();


            return _context.Roles
                .Where(u => u.Id == id)
                .SelectMany(r => r.RolePermissions)
                .Select(rp => rp.Permission)
                .Select(i => i.Id);        
        }

        /// <summary>
        /// 保存角色
        /// </summary>        
        public Role SaveRole(Role input)
        {            
            if (input.Id == 0)
            {
                var hasData = _context.Roles.FirstOrDefault(m => m.Name == input.Name);
                if (hasData != null)
                {
                    throw new Exception("已存在此角色名称");
                }
                var user = new Role()
                {
                    Name = input.Name,
                    Remark = input.Remark,
                };
                _context.Roles.Add(user);
                _context.SaveChanges();

                var role = _context.Roles.OrderBy(s => s.Id).Last();                
                return role;
            }
            else
            {
                var hasData = _context.Roles.FirstOrDefault(m => m.Name == input.Name && m.Id != input.Id);
                if (hasData != null)
                {
                    throw new Exception("已存在此角色名称");
                }              
                //_context.Roles.Update(input);
                _context.SaveChanges();
                return input;
            }
        }

        /// <summary>
        /// 删除角色
        /// </summary>
        public void DeleteRole(long id)
        {                 
            var role = _context.Roles.FirstOrDefault(s => s.Id == id);
            if (role != null)
            {
                _context.Roles.Remove(role!);
                _context.SaveChanges();
            }
        }

        /// <summary>
        /// 为角色分配权限
        /// </summary>
        public void AssignRoleSecurity(RolePermissionInput input)
        {
            input.PermissionIds ??= Array.Empty<long>();
            var old = _context.RolePermissions.Where(u => u.RoleId == input.RoleId);
            _context.RolePermissions.RemoveRange(old);

            var list = new List<RolePermission>();
            foreach (var securityId in input.PermissionIds)
            {
                list.Add(new RolePermission { 
                    RoleId = input.RoleId, 
                    PermissionId = securityId }
                );
            }
            _context.RolePermissions.AddRange(list);
            _context.SaveChanges();
        }

        /// <summary>
        /// 查询员工
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public IEnumerable<User> SearchUser(SimpleInput input)
        {
            if (!string.IsNullOrEmpty(input.keyword))
                 return _context.Users.Where(m => m.Name.Contains(input.keyword) || m.Account.Contains(input.keyword));
            return _context.Users.AsEnumerable();
        }
        
        /// <summary>
        /// 保存员工
        /// </summary>
        public void SaveUser(User input)
        {            
            var isExist = _context.Users.Any(m => m.Account == input.Account && m.Id != input.Id);
            if (isExist)
            {
                throw new Exception("已存在此账号");
            }

            if (input.Id == 0)
            {
                User user = new User()
                {
                    Id = input.Id,
                    Account = input.Account,
                    Name = input.Name,
                    Password = "123456",
                    Phone = input.Phone,
                    Remark = input.Remark,
                };
                _context.Users.Add(user);
                _context.SaveChanges();
                var last = _context.Users.OrderBy(s => s.Id).Last();
                input.Id = last.Id;
            }
            else
            {
                var oldUser = _context.Users.FirstOrDefault(m => m.Id == input.Id);
                if (oldUser == null)
                {
                    throw new Exception("员工不存在");
                }
                oldUser.Account = input.Account;
                oldUser.Name = input.Name;
                oldUser.Phone = input.Phone;
                oldUser.Remark = input.Remark;
                _context.Users.Update(oldUser);
                _context.SaveChanges();
            }            
        }

        /// <summary>
        /// 删除员工
        /// </summary>
        public void DeleteEmployee(long id)
        {
            var selfId = AppSession.User!.Id;
            if (selfId == id)
            {
                throw new Exception("不能删除自己");
            }
            var user = _context.Users.FirstOrDefault(u => u.Id == id);
            _context.Users.Remove(user!);
            _context.SaveChanges();
        }

        /// <summary>
        /// 获取某个员工的角色
        /// </summary>
        public IEnumerable<Role> GetRoleByUserId(long id)
        {
            return _context.Users
                .Where(u => u.Id == id)
                .SelectMany(r => r.UserRoles)
                .Select(rp => rp.Role).AsEnumerable();                
        }

        /// <summary>
        /// 为用户分配角色
        /// </summary>
        public void GiveUserRole(UserRoleInput input)
        {
            // 获取用户Id
            input.RoleIds ??= Array.Empty<long>();
            var userRoels = _context.UserRoles.Where(u => u.UserId == input.UserId);
            _context.UserRoles.RemoveRange(userRoels);

            var list = new List<UserRole>();
            foreach (var id in input.RoleIds)
            {
                list.Add(
                    new UserRole 
                    { 
                        UserId = input.UserId, 
                        RoleId = id 
                    });
            }
            _context.UserRoles.AddRange(list);
            _context.SaveChanges();
        }
    }
}
